<template>
  <div class="container">
    <canvas ref="canvas"></canvas>
  </div>
</template>

<script>
export default {
  name: 'LayeredGlowingTree',
  data() {
    return {
      ctx: null,
      particles: [],
      lights: [],
      snowflakes: [],
      animationFrame: null
    }
  },
  mounted() {
    this.initCanvas()
    this.createTree()
    this.animate()
  },
  beforeUnmount() {
    cancelAnimationFrame(this.animationFrame)
  },
  methods: {
    initCanvas() {
      const canvas = this.$refs.canvas
      canvas.width = window.innerWidth
      canvas.height = window.innerHeight
      this.ctx = canvas.getContext('2d')
    },
    createTree() {
      const centerX = window.innerWidth / 2
      const centerY = window.innerHeight / 2
      const spacing = 2.5  // 减小粒子间距，增加密度
      const layerGap = 15  // 层间距

      // 定义每层的参数
      const layers = [
        { topWidth: 0, bottomWidth: 60, height: 50, curve: 12 },    // 顶层三角形
        { topWidth: 40, bottomWidth: 100, height: 60, curve: 15 },  // 第二层
        { topWidth: 80, bottomWidth: 150, height: 60, curve: 18 },  // 第三层
        { topWidth: 120, bottomWidth: 200, height: 60, curve: 20 }  // 底层
      ]

      // 创建树干
      const trunkWidth = 30
      const trunkHeight = 60
      const totalTreeHeight = layers.reduce((sum, layer) => sum + layer.height, 0)
        + (layers.length - 1) * layerGap
      const trunkY = centerY - 180 + totalTreeHeight

      // 创建树干粒子
      for (let y = 0; y < trunkHeight; y += spacing) {
        for (let x = -trunkWidth / 2; x < trunkWidth / 2; x += spacing) {
          if (Math.random() > 0.05) {  // 降低随机过滤概率，增加树干密度
            const brightness = 20 + Math.random() * 10
            this.particles.push({
              x: centerX + x + (Math.random() - 0.5),
              y: trunkY + y + (Math.random() - 0.5),
              radius: Math.random() * 1.2 + 0.8,
              color: `hsla(30, 60%, ${brightness}%, 0.8)`,
              glow: Math.random() * 5,
              speed: Math.random() * 0.01,
              isTrunk: true
            })
          }
        }
      }

      // 创建树冠粒子
      let currentY = centerY - 180
      const particleCache = []

      layers.forEach((layer, index) => {
        for (let y = 0; y < layer.height; y += spacing) {
          const progress = y / layer.height
          const currentWidth = layer.topWidth + (layer.bottomWidth - layer.topWidth) * progress

          for (let x = -currentWidth / 2; x < currentWidth / 2; x += spacing) {
            if (Math.random() > 0.15) {  // 降低随机过滤概率，增加树冠密度
              const xRatio = (x / currentWidth + 0.5)
              const curveOffset = Math.pow(Math.sin(xRatio * Math.PI), 0.5) * layer.curve

              const brightness = 40 + Math.random() * 20
              particleCache.push({
                x: centerX + x + (Math.random() - 0.5),
                y: currentY + y + (progress > 0.7 ? curveOffset : 0),
                radius: Math.random() * 1.2 + 0.8,
                color: `hsla(200, 100%, ${brightness}%, 0.8)`,
                glow: Math.random() * 10,
                speed: Math.random() * 0.01,
                isTrunk: false
              })

              // 在弯曲处添加更多填充粒子
              if (progress > 0.7) {
                for (let fill = 0; fill < 2; fill++) {  // 每个位置添加多个填充粒子
                  if (Math.random() > 0.3) {
                    particleCache.push({
                      x: centerX + x + (Math.random() - 0.5) * 2,
                      y: currentY + y + curveOffset * Math.random(),
                      radius: Math.random() * 1.2 + 0.8,
                      color: `hsla(200, 100%, ${brightness}%, 0.8)`,
                      glow: Math.random() * 10,
                      speed: Math.random() * 0.01,
                      isTrunk: false
                    })
                  }
                }
              }

              // 添加额外的随机填充粒子
              if (Math.random() > 0.7) {
                particleCache.push({
                  x: centerX + x + (Math.random() - 0.5) * spacing,
                  y: currentY + y + (Math.random() - 0.5) * spacing,
                  radius: Math.random() * 1.2 + 0.8,
                  color: `hsla(200, 100%, ${brightness}%, 0.8)`,
                  glow: Math.random() * 10,
                  speed: Math.random() * 0.01,
                  isTrunk: false
                })
              }
            }
          }
        }
        currentY += layer.height + layerGap
      })

      // 一次性添加所有粒子
      this.particles.push(...particleCache)

      // 添加装饰灯
      currentY = centerY - 180
      layers.forEach((layer, layerIndex) => {
        const numLights = 5 + Math.floor(Math.random() * 3)  // 增加装饰灯数量
        for (let i = 0; i < numLights; i++) {
          const progress = i / (numLights - 1)
          const x = -layer.bottomWidth / 2 + layer.bottomWidth * progress
          const curveOffset = Math.pow(Math.sin(progress * Math.PI), 0.5) * layer.curve

          this.lights.push({
            x: centerX + x + (Math.random() - 0.5) * 8,
            y: currentY + layer.height + curveOffset + (Math.random() - 0.5) * 4,
            radius: Math.random() * 3 + 2,
            color: `hsla(${Math.random() * 360}, 100%, 70%, 0.9)`,
            glow: Math.random() * 15 + 8,
            speed: Math.random() * 0.02
          })
        }
        currentY += layer.height + layerGap
      })

      // 添加雪花
      for (let i = 0; i < 50; i++) {
        this.snowflakes.push({
          x: Math.random() * window.innerWidth,
          y: Math.random() * window.innerHeight,
          radius: Math.random() * 1.5 + 0.5,
          speed: Math.random() * 0.8 + 0.3,
          angle: Math.random() * Math.PI * 2
        })
      }
    },
    animate() {
      // 使用 requestAnimationFrame 的回调时间来控制渲染频率
      const now = Date.now()
      if (this.lastRender && now - this.lastRender < 16) { // 约60fps
        this.animationFrame = requestAnimationFrame(this.animate)
        return
      }
      this.lastRender = now

      // 创建渐变背景
      const gradient = this.ctx.createLinearGradient(0, 0, 0, window.innerHeight)
      gradient.addColorStop(0, '#0a1a2a')
      gradient.addColorStop(1, '#1a2a3a')
      this.ctx.fillStyle = gradient
      this.ctx.fillRect(0, 0, window.innerWidth, window.innerHeight)

      // 使用离屏canvas进行批量渲染
      const offscreen = document.createElement('canvas')
      offscreen.width = window.innerWidth
      offscreen.height = window.innerHeight
      const offCtx = offscreen.getContext('2d')

      // 批量绘制粒子
      this.particles.forEach(particle => {
        const glow = Math.sin(now * particle.speed) * 3
        offCtx.shadowBlur = particle.glow + glow
        offCtx.shadowColor = particle.color
        offCtx.fillStyle = particle.color
        offCtx.beginPath()
        offCtx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2)
        offCtx.fill()
      })

      // 将离屏canvas内容一次性绘制到主canvas
      this.ctx.drawImage(offscreen, 0, 0)

      // 绘制装饰灯
      this.lights.forEach(light => {
        const glow = Math.sin(Date.now() * light.speed) * 10
        this.ctx.shadowBlur = light.glow + glow
        this.ctx.shadowColor = light.color
        this.ctx.fillStyle = 'white'
        this.ctx.beginPath()
        this.ctx.arc(light.x, light.y, light.radius, 0, Math.PI * 2)
        this.ctx.fill()
      })

      // 绘制顶部星星
      const starGlow = Math.sin(Date.now() * 0.003) * 10
      this.ctx.shadowBlur = 30 + starGlow
      this.ctx.shadowColor = '#FFD700'
      this.ctx.fillStyle = '#FFD700'
      this.ctx.beginPath()
      this.ctx.arc(window.innerWidth / 2, window.innerHeight / 2 - 230, 8, 0, Math.PI * 2)
      this.ctx.fill()

      // 绘制雪花
      this.snowflakes.forEach(snow => {
        snow.y += snow.speed
        snow.x += Math.sin(snow.angle) * 0.5
        if (snow.y > window.innerHeight) {
          snow.y = 0
          snow.x = Math.random() * window.innerWidth
        }
        this.ctx.shadowBlur = 5
        this.ctx.shadowColor = 'white'
        this.ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'
        this.ctx.beginPath()
        this.ctx.arc(snow.x, snow.y, snow.radius, 0, Math.PI * 2)
        this.ctx.fill()
      })

      this.animationFrame = requestAnimationFrame(this.animate)
    }
  }
}
</script>

<style scoped>
.container {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  margin: 0;
  padding: 0;
  background: #0a1a2a;
}

canvas {
  display: block;
}

::-webkit-scrollbar {
  display: none;
}
</style>
